/*
 * Copyright © 2024-2025 Wenze Wei
 *
 * This file is part of StadionOS.
 *
 * This Source Code Form is subject to the terms of the GNU General Public License, v. 2.0.
 * You can obtain a copy of the GPL at
 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 */

#include "../include/fsd.h"

/**
 * @brief Reads data from a file descriptor.
 *
 * This function reads up to 'count' bytes from 'fd' into 'buf'.
 *
 * @param fd The file descriptor to read from.
 * @param buf The buffer to store the read data.
 * @param count The number of bytes to read.
 * @return ssize_t The number of bytes read, or -1 on error.
 */
ssize_t Sread(int fd, void *buf, size_t count)
{  
    return syscall(SYS_read, fd, buf, count);  
}

/**
 * @brief Reads a value associated with a key from a file (FOR SYSTEM COMPONENTS ONLY).
 *
 * This function reads the value associated with 'key' from the file specified by 'filename'.
 * It opens the file, reads line by line, and searches for the key. When the key is found,
 * it extracts the value, trims any leading or trailing whitespace, and copies it to 'buf'.
 * IMPORTANT: This function is critical and should only be used by system components.
 *
 * @param filename The path of the file to read from.
 * @param key The key to search for.
 * @param buf The buffer to store the read value.
 * @param bufsize The size of the buffer.
 * @return ssize_t The length of the value string, or -1 on error.
 */
ssize_t SXread(const char *filename, const char *key, void *buf, size_t bufsize) {
    int fd = SXopen(filename, "r", 0);
    if (fd < 0) {
        perror("SXopen");
        return -1;
    }

    char tempBuf[1024];
    ssize_t bytesRead;

    while ((bytesRead = Sread(fd, tempBuf, sizeof(tempBuf) - 1)) > 0) {
        tempBuf[bytesRead] = '\0';

        char *line = Sstrtok(tempBuf, "\n");
        while (line != NULL) {
            char *trimmedLine = line;
            while (*trimmedLine == ' ') trimmedLine++;

            char *equalSign = Sstrchr(trimmedLine, '=');
            if (equalSign != NULL) {
                *equalSign = '\0';

                if (Sstrncmp(trimmedLine, key, Sstrlen(key)) == 0) {
                    char *valueStart = equalSign + 1;

                    while (*valueStart == ' ') valueStart++;

                    char *valueEnd = valueStart;
                    while (*valueEnd != '\0' && *valueEnd != '\n') valueEnd++;

                    size_t valueLen = valueEnd - valueStart;

                    if (valueLen > bufsize - 1) {
                        valueLen = bufsize - 1;
                    }

                    Sstrncpy((char *)buf, valueStart, valueLen);
                    ((char *)buf)[valueLen] = '\0';

                    Sclose(fd);
                    return valueLen;
                }
            }

            line = Sstrtok(NULL, "\n");
        }
    }

    if (bytesRead < 0)
        perror("Sread");

    Sclose(fd);
    return -1;
}